#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'tian'
__data__ = '2021/12/15 14:53'
# software: PyCharm

import random
import re

from urllib import parse  # 处理url编码

from django.shortcuts import render
from django.db import transaction  # django事物
from django.http import JsonResponse, HttpResponse
from django.utils.encoding import escape_uri_path  # 下载文件名为中文乱码处理

from django.forms import model_to_dict
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from utils.encrypt import uid

from apps.app01 import models
from apps.app01.forms.file import FolderModelForm, DownLoad


def file(request):
    pid = request.GET.get("pid")  # pid是项目的pk
    if request.method == "GET" and not pid:
        it_obj = models.It.objects.all()
        return render(request, "it_all.html", {"it_dict": it_obj})

    parent_object = None
    folder_id = request.GET.get("folder", "")
    file_obj = models.FileRepository.objects.filter(project_id=pid)
    # 2是文件夹
    if folder_id.isdecimal():
        parent_object = file_obj.filter(id=int(folder_id), file_type=2).first()
    if request.method == "GET":
        breadcrumb_list = []
        parent = parent_object
        while parent:
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))  # [{'id': 6, 'name': '港湾置业1.8.0'}]
            parent = parent.parent
        # 当前目录下所有的文件 & 文件夹获取到即可
        if parent_object:
            # 进入某个目录
            file_object_list = file_obj.filter(parent=parent_object).order_by('-file_type')
        else:
            # 根目录
            file_object_list = file_obj.filter(parent__isnull=True).order_by('-file_type')
        form = FolderModelForm()
        file_obj = file_obj.first()
        context = {
            "form": form,
            "pid": pid,
            "file_object_list": file_object_list,
            "breadcrumb_list": breadcrumb_list,
            'folder_object': parent_object,
            "file_obj": file_obj.project.it_name if file_obj else "",
        }
        return render(request, "file.html", context)
    # POST添加或编辑文件夹
    fid = request.POST.get("fid", "")
    edit_object = None
    if fid.isdecimal():
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2).first()
    if edit_object:
        form = FolderModelForm(data=request.POST, instance=edit_object)
    else:
        form = FolderModelForm(data=request.POST)

    if form.is_valid():
        form.instance.file_type = 2
        form.instance.project_id = pid
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({"status": True})
    return JsonResponse({"status": False, "error": form.errors})


def file_delete(request):
    """
    删除
    :param request:
    :return:
    """
    fid = request.GET.get("fid")
    delete_object = models.FileRepository.objects.filter(id=fid).first()
    if delete_object.file_type == 1:
        delete_object.delete()
    else:
        delete_object.delete()
    return JsonResponse({"status": True})


@csrf_exempt
def file_size(request):
    """
    上传文件大小验证
    :param request:
    :return:
    """
    per_file_limit = settings.FILE_SIZE * 1024 * 1024
    file_list = request.FILES.getlist("f1", "")  # 上传文件对象
    parent_id = request.POST.get("fid", None)  # 进入目录ID
    for item in file_list:
        if item.size > per_file_limit:
            msg = "单文件超出限制(最大{0}M)。".format(item)
            return JsonResponse({'status': False, 'error': msg})
    file_li = []
    for file in file_list:
        name = file.name
        ext = name.split(".")[-1]
        str_random = "{0}.{1}".format(uid(random.randrange(999999)), ext)
        file_url = "http://{0}/file_download/{1}".format(request.get_host(), str_random)
        file_path = r"{0}\file\{1}".format(settings.MEDIA_ROOT, str_random)
        with open(file_path, "wb") as fr:
            for i in file.chunks():
                fr.write(i)
                try:
                    with transaction.atomic():
                        obj_create = models.FileRepository.objects.create(
                            project_id=request.POST.get("pid"),
                            file_type=1,
                            name=name,
                            file_rename=str_random,
                            file_size=file.size,
                            file_path=file_url,
                            parent_id=parent_id
                        )
                        result = {
                            "id": obj_create.pk,
                            "name": obj_create.name,
                            "file_size": obj_create.file_size,
                            "datetime": obj_create.update_datetime.strftime("%Y{0}%m{1}%d{2} %H:%M").format("年", "月",
                                                                                                            "日"),
                            "download_url": obj_create.file_path,
                        }
                        file_li.append(result)
                except Exception as er:
                    return JsonResponse({"status": False})
    return JsonResponse({"status": True, "data": file_li})


def file_download(request, file_name):
    """
    下载文件
    :param request:
    :return:
    """
    pid = request.GET.get("pid")
    if request.GET.get("pid"):
        obj_file = models.FileRepository.objects.filter(id=pid).first()
        path = "{0}\{1}\{2}".format(settings.MEDIA_ROOT, "file", obj_file.file_rename)
        name = obj_file.file_rename
    else:
        path = "{0}\{1}\{2}".format(settings.MEDIA_ROOT, "file", file_name)
        name = file_name
    with open(path, "rb") as f:
        data = f.read()
    response = HttpResponse(data)
    response["Content-Disposition"] = "attachment;filename={0}".format(escape_uri_path(name))
    return response


def apk_download(request):
    """
    下载apk
    :param request:
    :return:
    """

    pid = request.GET.get("pid")
    obj_file = models.UploadApk.objects.filter(id=pid).first()
    name = "{0}.apk".format(obj_file.apk_file)
    path = obj_file.file_path
    with open(path, "rb") as f:
        data = f.read()
    response = HttpResponse(data)
    response["Content-Disposition"] = "attachment;filename={0}".format(escape_uri_path(name))
    return response


def apk_home(request):
    """
    上传apk
    :param request:
    :return:
    """
    pid = request.GET.get("pid")  # pid是项目的pk
    if request.method == "GET" and not pid:
        it_obj = models.It.objects.all()
        return render(request, "apk_page.html", {"project_dict": it_obj})
    upload_obj = models.UploadApk.objects.filter(project_id=pid).order_by("-pk")
    file_obj = models.It.objects.filter(pk=pid).first()
    form = DownLoad()
    if request.method == "GET":
        content = {
            "pid": pid,
            "upload_obj": upload_obj,
            "file_obj": file_obj,
            "form": form,
        }
        return render(request, "apk_table.html", content)
    file_list = request.FILES.getlist("f1")  # 上传文件对象
    data = parse.unquote(request.POST.get("data"))  # url格式解码字符串
    name = re.findall(r"apk_file=(\w+)", data)
    context = re.findall(r"context=(\d+)", data)
    versions = re.findall(r"versions=(.+)&context", data)
    comment = re.findall(r"comment=(.+)", data)
    pid = request.POST.get("pid")
    fid = request.POST.get("fid")
    if fid != "undefined":
        if name:
            name = name[0]
        else:
            name = "暂无"
        if versions:
            versions = versions[0]
        else:
            versions = ""
        if comment:
            comment = comment[0]
        else:
            comment = ""
        models.UploadApk.objects.filter(pk=fid).update(
            apk_file=name,
            versions=versions,
            context=context[0],
            comment=comment,
        )
        return JsonResponse({"status": True})
    if file_list:
        file_list = file_list[0]
        if not name:
            name = file_list.name
        else:
            name = name[0]
        if versions:
            versions = versions[0]
        else:
            versions = ""

        if context:
            context = context[0]

        if comment:
            comment = comment[0]
        else:
            comment = ""

        str_random = "{0}.{1}".format(uid(random.randrange(999999)), "apk")
        file_path = r"{0}\apk\{1}".format(settings.MEDIA_ROOT, str_random)
        with open(file_path, "wb") as fr:
            for i in file_list.chunks():
                fr.write(i)
        try:
            with transaction.atomic():
                models.UploadApk.objects.create(
                    project_id=pid,
                    apk_file=name,
                    versions=versions,
                    context=context,
                    file_path=file_path,
                    comment=comment,
                )
        except Exception as error:
            return JsonResponse({"status": False, "error": error})
        return JsonResponse({"status": True})
    else:
        return JsonResponse({"status": False, "error": "必填字段"})


def apk_delete(request):
    """删除apk"""
    fid = request.GET.get("fid")
    models.UploadApk.objects.filter(id=fid).first().delete()
    return JsonResponse({"status": True})
